home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1993 / Internet Info CD-ROM (Walnut Creek) (1993).iso / networking / athena / moira / moira.tar.Zaa / moira.tar.Zaa / gen / nfs.qc < prev    next >
Encoding:
Text File  |  1990-03-22  |  10.0 KB  |  388 lines

  1. /* $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/gen/RCS/nfs.qc,v 1.18 90/03/19 19:07:10 mar Exp $
  2.  *
  3.  * This generates the files necessary to load an nfs server.
  4.  *
  5.  *  (c) Copyright 1988 by the Massachusetts Institute of Technology.
  6.  *  For copying and distribution information, please see the file
  7.  *  <mit-copyright.h>.
  8.  */
  9.  
  10. #include <mit-copyright.h>
  11. #include <stdio.h>
  12. #include <moira.h>
  13. #include <moira_site.h>
  14. #include <sys/types.h>
  15. #include <sys/stat.h>
  16. #include <sys/time.h>
  17.  
  18.  
  19. #define min(x,y)    ((x) < (y) ? (x) : (y))
  20.  
  21. char *whoami = "nfs.gen";
  22. char *malloc(), *strsave();
  23. char *ingres_date_and_time(), *ingres_time(), *ingres_date();
  24. char nfs_dir[64];
  25.  
  26. main(argc, argv)
  27. int argc;
  28. char **argv;
  29. {
  30.     char cmd[64];
  31.     struct stat sb;
  32.     int changed = 0;
  33.     int ingerr();
  34.  
  35.     if (argc > 2) {
  36.     fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
  37.     exit(MR_ARGS);
  38.     }
  39.  
  40.     IIseterr(ingerr);
  41.     initialize_sms_error_table();
  42.     sprintf(nfs_dir, "%s/nfs", DCM_DIR);
  43.  
  44. ##  ingres sms
  45. ##  set lockmode session where level = table
  46.  
  47.     changed = do_nfs();
  48.  
  49. ##  exit
  50.  
  51.     if (!changed) {
  52.     fprintf(stderr, "No files updated.\n");
  53.     if (argc == 2 && stat(argv[1], &sb) == 0)
  54.       exit(MR_NO_CHANGE);
  55.     }
  56.  
  57.     if (argc == 2) {
  58.     sprintf(cmd, "cd %s; cp %s/nfs/* .; tar cf %s .",
  59.         nfs_dir, SMS_DIR, argv[1]);
  60.     if (system(cmd))
  61.       exit(MR_TAR_FAIL);
  62.     }
  63.  
  64.     exit(MR_SUCCESS);
  65. }
  66.  
  67.  
  68. /*
  69.  * ingerr: (supposedly) called when Ingres indicates an error.
  70.  * I have not yet been able to get this to work to intercept a
  71.  * database open error.
  72.  */
  73. #define INGRES_DEADLOCK 4700
  74.  
  75. static int ingerr(num)
  76.     int *num;
  77. {
  78.     char buf[256];
  79.     int ingres_errno;
  80.  
  81.     switch (*num) {
  82.     case INGRES_DEADLOCK:
  83.     ingres_errno = MR_DEADLOCK;
  84.     break;
  85.     default:
  86.     ingres_errno = MR_INGRES_ERR;
  87.     }
  88.     com_err(whoami, MR_INGRES_ERR, " code %d\n", *num);
  89.     critical_alert("DCM", "NFS build encountered INGRES ERROR %d", *num);
  90.     exit(ingres_errno);
  91. }
  92.  
  93.  
  94. /* Generate the files.  Returns zero if nothing changed, non-zero otherwise. */
  95.  
  96. int do_nfs()
  97. ##{
  98. ##  char machname[33], listname[33];
  99.     struct save_queue *machs, *lists;
  100.     int changed;
  101.  
  102.     machs = sq_create();
  103.     lists = sq_create();
  104. ##  range of s is serverhosts
  105. ##  retrieve (machname = machine.name, listname = s.value3)
  106. ##    where machine.mach_id = s.mach_id and s.service = "NFS"
  107. ##    and s.enable != 0 {
  108.       sq_save_unique_string(machs, strsave(strtrim(machname)));
  109.       sq_save_unique_string(lists, strsave(strtrim(listname)));
  110. ##  }
  111.  
  112.     changed = do_lists(lists);
  113.     changed += do_machs(machs);
  114.     return(changed);
  115. ##}
  116.  
  117.  
  118. /* Make all of the credentials lists that will be needed.  Returns 0 if
  119.  * no files were actually changed */
  120.  
  121. int do_lists(lists)
  122. struct save_queue *lists;
  123. ##{
  124.     char file[64], *u;
  125.     struct hash *users, *do_everyone();
  126.     struct stat sb;
  127.     FILE *fd;
  128. ##  char *listname, *lsname, lname[33], uname[9], *filetime;
  129. ##  int uid, id, flag1, flag2, flag3, flag4;
  130.  
  131.     sprintf(file, "%s/list-", nfs_dir);
  132.     if (stat(file, &sb) == 0) {
  133.     filetime = ingres_date_and_time(sb.st_mtime);
  134. ##    retrieve (flag1 = int4(interval("min", tblstats.modtime - filetime)))
  135. ##        where tblstats.table = "users"
  136. ##    retrieve (flag2 = int4(interval("min", tblstats.modtime - filetime)))
  137. ##        where tblstats.table = "list"
  138. ##    retrieve (flag3 = int4(interval("min", tblstats.modtime - filetime)))
  139. ##        where tblstats.table = "imembers"
  140. ##    retrieve (flag4 = int4(interval("min", tblstats.modtime - filetime)))
  141. ##        where tblstats.table = "serverhosts"
  142.     if (flag1 < 0 && flag2 < 0 && flag3 < 0 && flag4 < 0) {
  143.         fprintf(stderr, "The lists do not need to be rebuilt.\n");
  144.         return(0);
  145.     }
  146.     }
  147.  
  148. ##  begin transaction
  149.     /* get locks */
  150. ##  retrieve (lname = list.modtime) where list.list_id = 0
  151. ##  retrieve (lname = users.modtime) where users.users_id = 0
  152.  
  153.     /* build the list of everyone, and store it in a file whose name
  154.      * corresponds to the empty list.
  155.      */
  156.     users = do_everyone();
  157.  
  158.     fprintf(stderr, "Building specific lists\n");
  159.     /* now do each of the lists used by an NFS server */
  160. ##  range of l is list
  161. ##  range of l1 is list
  162. ##  range of m is imembers
  163. ##  range of u is users
  164.     while (sq_get_data(lists, &listname)) {
  165.     if (strlen(listname) == 0)
  166.       continue;
  167.     sprintf(file, "%s/list-%s", nfs_dir, listname);
  168.     fd = fopen(file, "w");
  169.     if (!fd) {
  170.         fprintf(stderr, "cannot open %s for output\n", file);
  171.         exit(MR_OCONFIG);
  172.     }
  173. ##    repeat retrieve (id = m.member_id)
  174. ##        where m.list_id = l1.list_id and l1.name = @listname and
  175. ##        m.member_type = "USER" {
  176.         if (u = hash_lookup(users, id))
  177.           fprintf(fd, "%s\n", u);
  178. ##    }
  179.     if (fclose(fd)) {
  180.         fprintf(stderr, "error closing %s\n", file);
  181.         exit(MR_CCONFIG);
  182.     }
  183.     }
  184. /* don't free here either
  185.     sq_destroy(lists);
  186.  */
  187. ##  end transaction
  188.     return(1);
  189. ##}
  190.  
  191.  
  192. /*  Build the list of everybody. */
  193. struct grp {
  194.     struct grp *next;
  195.     char *lid;
  196. };
  197. struct user {
  198.     char name[9];
  199.     int uid;
  200.     struct grp *lists;
  201. };
  202.  
  203. struct hash *do_everyone()
  204. ##{
  205.     char buf[BUFSIZ], *l;
  206.     struct hash *groups, *users;
  207.     struct user *u;
  208.     struct grp *g;
  209.     struct bucket *b, **p;
  210. ##  char name[33];
  211. ##  int gid, id, lid, maxid, uid;
  212.     FILE *fd;
  213.     int i;
  214.     struct save_queue *sq;
  215.  
  216.     fprintf(stderr, "Building the list of everybody\n");
  217.     sprintf(buf, "%s/list-", nfs_dir);
  218.     fd = fopen(buf, "w");
  219.     if (!fd) {
  220.     fprintf(stderr, "cannot open %s for output\n", buf);
  221.     exit(MR_OCONFIG);
  222.     }
  223.  
  224.     /* make space for group list */
  225.     groups = create_hash(15000);
  226.  
  227.     /* retrieve simple groups */
  228. ##  range of l is list
  229. ##  retrieve (gid = l.#gid, lid = l.list_id)
  230. ##    where l.group != 0 and l.active != 0 {
  231.       sprintf(buf, ":%d", gid);
  232.       hash_store(groups, lid, strsave(buf));
  233. ##  }
  234.  
  235.     /* now do grplists */
  236.     users = create_hash(10000);
  237. ##  range of u is users
  238. ##  retrieve (id = u.users_id, name = u.login, uid = u.#uid)
  239. ##     where u.status = 1 {
  240.       u = (struct user *) malloc(sizeof(struct user));
  241.       strcpy(u->name, strtrim(name));
  242.       u->uid = uid;
  243.       u->lists = NULL;
  244.       hash_store(users, id, u);
  245. ##  }
  246.  
  247. ##  range of m is imembers
  248. ##  retrieve (lid = m.list_id, id = m.member_id) where m.member_type = "USER" {
  249.       if ((u = (struct user *) hash_lookup(users, id)) &&
  250.       ((l = hash_lookup(groups, lid)) != NULL)) {
  251.       g = (struct grp *) malloc(sizeof(struct grp));
  252.       g->next = u->lists;
  253.       u->lists = g;
  254.       g->lid = l;
  255.       }
  256. ##  }
  257.  
  258.     for (p = &(users->data[users->size - 1]); p >= users->data; p--) {
  259.     for (b = *p; b; b = b->next) {
  260.         u = (struct user *)b->data;
  261.         sprintf(buf, "%s:%d", u->name, u->uid);
  262.         for (g = u->lists; g; g = g->next)
  263.           strcat(buf, g->lid);
  264.         b->data = strsave(buf);
  265.         fprintf(fd, "%s\n", buf);
  266.     }
  267.     }
  268.  
  269.     fclose(fd);
  270.     free(groups);
  271.     return(users);
  272. ##}
  273.  
  274.  
  275. /* Now do each of the servers, linking the credentials list file and 
  276.  * compiling the quota and dirs files.
  277.  */
  278.  
  279. int do_machs(machs)
  280. struct save_queue *machs;
  281. ##{
  282. ##  char *machname, listname[33], dev[33], dir[81], fstype[9];
  283. ##  int uid, quota, id, gid, flag1, flag2, flag3, flag4;
  284.     char file[64], f1[64], f2[64], *cp, *index();
  285.     int prevuid, quotasum, olddev, oldmach;
  286.     FILE *fd;
  287.     struct hash *machines;
  288.  
  289.     fprintf(stderr, "Building machine files\n");
  290.  
  291. ##  range of s is serverhosts
  292. ##  range of m is machine
  293. ##  range of n is nfsphys
  294. ##  range of q is nfsquota
  295. ##  range of f is filesys
  296. ##  range of u is users
  297. ##  range of l is list
  298.  
  299. /* acquire locks on machines & filesystems */
  300. ##  begin transaction
  301. ##  retrieve (listname = u.modtime) where u.users_id = 0
  302. ##  retrieve (listname = m.modtime) where m.mach_id = 0
  303. ##  retrieve (listname = f.modtime) where f.filsys_id = 0
  304.  
  305.     machines = create_hash(100);
  306.     while (sq_get_data(machs, &machname)) {
  307. ##    repeat retrieve (listname = s.value3, id = m.mach_id)
  308. ##        where s.mach_id = m.mach_id and m.name = @machname
  309.     strtrim(machname);
  310.     sprintf(f1, "%s/list-%s", nfs_dir, strtrim(listname));
  311.     sprintf(f2, "%s/%s.cred", nfs_dir, machname);
  312.     unlink(f2); /* ignore errors on this unlink */
  313.     if (link(f1, f2)) {
  314.         fprintf(stderr, "Cannot link %s to %s\n", f1, f2);
  315.         exit(MR_OCONFIG);
  316.     }
  317.     hash_store(machines, id, machname);
  318.     }
  319.  
  320.     olddev = oldmach = -1;
  321.     fd = stdin;
  322. ##  retrieve (quota = q.#quota, uid = u.#uid, flag1 = q.phys_id,
  323. ##          dev = n.device, flag2 = n.mach_id)
  324. ##    where u.users_id = q.users_id and n.nfsphys_id = q.phys_id and
  325. ##          q.phys_id != 0
  326. ##    sort by #flag2, #flag1, #uid {
  327.       if (flag1 != olddev || flag2 != oldmach) {
  328.       fclose(fd);
  329.       olddev = flag1;
  330.       oldmach = flag2;
  331.       while (cp = index(dev, '/')) *cp = '@';
  332.       sprintf(file, "%s/%s.%s.quotas", nfs_dir,
  333.           hash_lookup(machines, flag2), strtrim(dev));
  334.       fd = fopen(file, "w");
  335.       if (!fd) {
  336.           fprintf(stderr, "cannot open %s for output\n", file);
  337.           exit(MR_OCONFIG);
  338.       }
  339.       prevuid = -1;
  340.       quotasum = 0;
  341.       }
  342.       if (uid != prevuid) {
  343.       if (quotasum)
  344.         fprintf(fd, "%d %d\n", prevuid, quotasum);
  345.       prevuid = uid;
  346.       quotasum = quota;
  347.       } else {
  348.       quotasum += quota;
  349.       }
  350. ##  }
  351.     if (quotasum)
  352.       fprintf(fd, "%d %d\n", prevuid, quotasum);
  353.     if (fclose(fd)) {
  354.     fprintf(stderr, "error closing %s", file);
  355.     exit(MR_CCONFIG);
  356.     }
  357.  
  358.     olddev = oldmach = -1;
  359. ##  retrieve (dir = f.#name, fstype = f.lockertype, uid = u.#uid,
  360. ##          gid = l.#gid, flag1 = f.phys_id, flag2 = f.mach_id,
  361. ##          dev = n.device)
  362. ##    where u.users_id = f.owner and l.list_id = f.owners and
  363. ##          f.createflg != 0 and f.phys_id != 0 and f.type = "NFS" and
  364. ##          f.phys_id = n.nfsphys_id
  365. ##    sort by #flag2, #flag1 {
  366.       if (flag1 != olddev || flag2 != oldmach) {
  367.       fclose(fd);
  368.       olddev = flag1;
  369.       oldmach = flag2;
  370.       while (cp = index(dev, '/')) *cp = '@';
  371.       sprintf(file, "%s/%s.%s.dirs", nfs_dir,
  372.           hash_lookup(machines, flag2), strtrim(dev));
  373.       fd = fopen(file, "w");
  374.       if (!fd) {
  375.           fprintf(stderr, "cannot open %s for output\n", file);
  376.           exit(MR_OCONFIG);
  377.       }
  378.       }
  379.       fprintf(fd, "%s %d %d %s\n", strtrim(dir), uid, gid, strtrim(fstype));
  380. ##  }
  381.     if (fclose(fd)) {
  382.     fprintf(stderr, "error closing %s", file);
  383.     exit(MR_CCONFIG);
  384.     }
  385. ##  end transaction
  386.     return(1);
  387. ##}
  388.